
// Component base class for easy creation of XPCOM components

function pcComponent() { }

pcComponent.prototype = 
{
	// NOTE: Just set these to implement a new component.
	mCID : null,
	mProgID : null,
	mName : null,

	// aFirstTime is a flag used only when the component is initially registered.
	aFirstTime : true,

	// Factory
	createComponent : function()
	{
		return null;
	},

	// nsISupports
	QueryInterface : function(iid)
	{
		if (iid.equals(Components.interfaces.nsIModule))
			return this;
		else if (iid.equals(Components.interfaces.nsIFactory))
			return this;
		else if (iid.equals(Components.interfaces.nsISupports))
			return this;

        Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
        return null;
	},
	
	// nsIModule
	registerSelf : function(compMgr, fileSpec, location, type)
	{
		if (this.aFirstTime) 
		{
			dump(" **** First time registration of * " + this.mName + " component ****\n");
			this.aFirstTime = false;
			throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
		}
		
		dump("**** Registering * " + this.mName + " component (all right -- a generic JS module!)\n");
		compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
		
		// All these members have to be set in derived class.
		compMgr.registerFactoryLocation(this.mCID, this.mName, this.mProgID, 
			fileSpec, location, type);
	},
	
	getClassObject : function(compMgr, cid, iid)
	{
		if (!cid.equals(this.mCID))
			throw Components.results.NS_ERROR_NO_INTERFACE;
		
		if (!iid.equals(Components.interfaces.nsIFactory))
			throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
			
		return this;
	},
	
	canUnload : function(compMgr)
	{
		dump(" **** Unloading: " + this.mName + " component ****\n");
		return true;
	},
	
	// nsIFactory
	createInstance : function(outer, iid)
	{
		if (outer != null)
			throw Components.results.NS_ERROR_NO_AGGREGATION;
			
		return this.createComponent().QueryInterface(iid);
	}
};
